﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Convertor.Interface;
using Wpf.CommonTools.StaticExtension;
using Wpf.CommonTools.SystemExtension;

namespace Convertor
{
    public class ConvertHelper : IConvertHelper
    {
        private IPluginItem runToPluginItem;

        public IPluginItem RunToPluginItem
        {
            get { return runToPluginItem; }
            set { runToPluginItem = value; }
        }
        private IConvertParamters parentContent;

        public IConvertParamters ParentContent
        {
            get { return parentContent; }
            set { parentContent = value; }
        }

        public IConvertParamters OutputFunc(IConvertParamters content, Collection<IPluginItem> selectedPlugins, object parentOutput = null)
        {
            //content.Stop = false;
            if (parentContent == null)
            {
                parentContent = content;
            }

            IConvertParamters output = content.Copy();

            foreach (PluginItem item in selectedPlugins)
            {
                if (output == null || output.StopConvert)
                {
                    return output;
                }
                else if (item.ParentPlugin == null)
                {
                    output = Convert(output, item);
                }
                else
                {
                    IList iEnumerableOutput = output.OutputContent as IList;
                    if (iEnumerableOutput == null)
                    {
                        output = Convert(output, item);
                    }
                    else
                    {
                        List<object> list = new List<object>();
                        foreach (object outputValue in iEnumerableOutput)
                        {
                            IConvertParamters ou = new ConvertParamters(output.LastInputContent, outputValue);
                            object o = Convert(ou, item).OutputContent;
                            list.Add(o);
                        }
                        output.OutputContent = list;
                    }
                }

                if (Elapsed != null && parentOutput == null)
                {
                    Elapsed(this, null);
                }

                if (runToPluginItem != null && item.UiqueId == runToPluginItem.UiqueId)
                {
                    runToPluginItem = null;
                    content.StopConvert = true;
                    return output;
                }
            }
            return output;
        }

        public IConvertParamters Convert(IConvertParamters content, IPluginItem item)
        {
            IConvert iConvert = setPluginConfig(item);
            if (iConvert == null)
                return null;
            Config.ProcesingPluginNameModel.ProcessingPluginName = item.Name;
            IConvertParamters output = iConvert.Output(content);
            if (item.ChildPlugins != null && item.ChildPlugins.Count > 0)
            {
                output = OutputFunc(output, item.ChildPlugins, output.OutputContent);
            }
            return output;
        }

        private object getInputValue(IList iEnumerableInput, int i)
        {
            object lastOriginalValue = null;
            if (iEnumerableInput != null)
            {
                int j = 0;
                foreach (object kk in iEnumerableInput)
                {
                    if (j == i)
                    {
                        lastOriginalValue = kk;
                        break;
                    }
                    j++;
                }
            }
            return lastOriginalValue;
        }

        private IConvert setPluginConfig(IPluginItem item)
        {
            if (!Config.GlobalConfig.AllPlugins.ContainsKey(item.Path))
            {
                return null;
            }
            object plugin = Config.GlobalConfig.AllPlugins[item.Path];

            PluginBase p = plugin as PluginBase;
            if (p != null)
            {
                p.Config = ((IPluginConfig)item).Config;
                p.Log = Log;
                p.Loader = new PluginConfigLoader() { PluginContent = item, Plugin = plugin, GenerateLoader = generate };
            }

            IPluginLoadPluginItems iLoadItem = plugin as IPluginLoadPluginItems;
            if (iLoadItem != null)
            {
                iLoadItem.LoadPluginItems = PluginHandler.GetPluginsFromTemplateByUniqueId;
            }

            IPluginOutputHeler iOutHelper = plugin as IPluginOutputHeler;
            if (iOutHelper != null)
            {
                iOutHelper.OutputFunc = new ConvertHelper();
                iOutHelper.OutputFunc.Log = Log;
            }

            return p;
        }

        private LoadConfigWindow generate(IPluginItem pluginContent, object plugin)
        {
            return new LoadConfigWindow(pluginContent, plugin, parentContent, Convert);
        }

        #region IPluginLog 成员

        public LogDelegate Log { set; private get; }

        #endregion

        #region IConvertHelper 成员

        public event System.Timers.ElapsedEventHandler Elapsed;

        #endregion
    }
}
